package com.base.controller;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.base.exception.BusinessException;
import com.base.utils.CookieUtil;
import com.base.vo.LoginUserInfo;
import com.base.vo.NullObject;
import com.base.vo.Response;
import com.base.vo.ReturnCodeEnum;

/**
 * @类描述：登录登出
 * @创建人：wangdw
 * @创建时间：2018年12月5日 上午9:27:39
 */
@RestController
@RequestMapping
public class LoginController extends BaseController {
    
    /**
     * 方法描述：跳转到SSO页面
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("login")
    public void toLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            String requestUrl = request.getRequestURL().toString();
            String ticket = UUID.randomUUID().toString();// request.getParameter("ticket");
            String redirect = request.getParameter("redirect");
            // if (StringUtils.isBlank(ticket)) {// 登录
            // String param = URLEncoder.encode(requestUrl + "?redirect=" + redirect, "utf-8");
            // String url = "ssologin?service=" + param;
            // logger.info("跳转到登录页面，url:{}", url);
            // response.sendRedirect(url);
            // return;
            // }
            
            LoginUserInfo userInfo = getAndCacheUserInfo(ticket);
            
            setCookie(response, ticket, userInfo);
            
            if (StringUtils.isBlank(redirect) || "null".equalsIgnoreCase(redirect)) {
                response.sendRedirect(request.getContextPath() + "/index");
            } else {
                response.sendRedirect(redirect);
            }
        } catch (Exception e) {
            BusinessException.error("单点登录异常", e);
            request.setAttribute("errorMsg", e.getMessage());
            request.getRequestDispatcher("error").forward(request, response);
        }
    }
    
    /**
     * 方法描述：退出登录
     * @return
     */
    @GetMapping("logout")
    public Response<NullObject> logout(HttpServletRequest request, HttpServletResponse response) {
        Response<NullObject> res = new Response<>();
        try {
            // 清除redis
            this.delRedis(request);
            // 清除cookie
            this.delCookie(response);
        } catch (Exception e) {
            BusinessException.info("退出登录异常", e);
            res = new Response<>(ReturnCodeEnum.CODE_9999.getCode(), e.getMessage());
        }
        return res;
    }
    
    /**
     * 方法描述：获取用户信息并缓存到Redis
     * @param ticket
     * @throws Exception
     */
    private LoginUserInfo getAndCacheUserInfo(String ticket) throws Exception {
        // 根据SSO返回的票据获取用户名TODO
        
        LoginUserInfo userInfo = new LoginUserInfo();
        userInfo.setUserId("zhangsan");
        userInfo.setUserName("张三");
        
        // 把用户信息存到redis
        redisHelper.set(USER_KEY + ticket, userInfo, 60 * 30);// 缓存30分钟
        return userInfo;
    }
    
    /**
     * 方法描述：把token及用户信息写到cookie
     * @param response
     * @param ticket
     * @param userInfo
     * @throws UnsupportedEncodingException
     */
    private void setCookie(HttpServletResponse response, String ticket, LoginUserInfo userInfo) throws UnsupportedEncodingException {
        Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, ticket);
        cookie.setPath("/");// 设置path为空，否则开发环境取不到cookie
        cookie.setDomain("");// 跨域共享cookie（".cjeye.net"）
        cookie.setMaxAge(60 * 60 * 12);// 有效期12小时
        
        // userInfo.setPermissions(null);// 清空权限，数据量太大，会报HeadersTooLargeException异常
        Cookie userCookie = new Cookie("userInfo", URLEncoder.encode(JSONObject.toJSONString(userInfo), "utf-8"));
        userCookie.setPath("/");
        userCookie.setDomain("");
        userCookie.setMaxAge(60 * 60 * 12);// 有效期12小时
        
        response.addCookie(cookie);
        response.addCookie(userCookie);
    }
    
    /**
     * 方法描述：清除用户cookie
     * @param response
     */
    private void delCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie(TOKEN_COOKIE_NAME, null);
        cookie.setPath("/");// 设置path为空，否则开发环境取不到cookie
        cookie.setDomain("");// 跨域共享cookie（".cjeye.net"）
        cookie.setMaxAge(0);// 失效
        
        Cookie userCookie = new Cookie("userInfo", null);
        userCookie.setPath("/");
        userCookie.setDomain("");
        userCookie.setMaxAge(0);// 失效
        
        response.addCookie(cookie);
        response.addCookie(userCookie);
    }
    
    /**
     * 方法描述：清除缓存的用户信息
     * @param request
     */
    private void delRedis(HttpServletRequest request) {
        String token = CookieUtil.getCookie(request, TOKEN_COOKIE_NAME);
        logger.debug("logout.delRedis:{}", token);
        redisHelper.del(USER_KEY + token);
    }
}
